import json
from PyQt6.QtCore import pyqtSignal, QObject
from PyQt6.QtWidgets import QWidget, QLabel
import numpy as np
import pyqtgraph as pg
from typing import Dict, Any, Optional, List
from collections import deque


class Chart:
    """单个图表的封装 - 消除数据重复"""
    
    def __init__(self, config: Dict[str, Any]):
        self.config = config
        self.data_source: Optional[str] = config.get('data_source', None)
        self.plot_widget = self._create_plot_widget()
        self.curves: Dict[str, Any] = {}
        self._setup_curves()
    
    def _create_plot_widget(self) -> pg.PlotWidget:
        """创建图表控件"""
        plot_widget = pg.PlotWidget()
        
        # 网格设置
        show_grid = self.config.get('show_grid', {})
        plot_widget.showGrid(x=show_grid.get('x', False), y=show_grid.get('y', False))
        
        # 标签设置
        plot_widget.addLegend()
        plot_widget.setLabel('bottom', self.config.get('x_axis_label', 'Time'), units=self.config.get('x_axis_unit', 'ms'))
        plot_widget.setLabel('left', self.config.get('y_axis_label', ''))
        
        # Y轴范围设置
        y_limit = self.config.get('y_axis_limit', [0, 0])
        if y_limit != [0, 0]:  # 简化条件判断
            plot_widget.setYRange(y_limit[0], y_limit[1])
        
        return plot_widget
    
    def _setup_curves(self) -> None:
        """设置曲线"""
        y_data_list = self.config.get('y_data', [])
        y_colors = self.config.get('y_color', [])
        
        for i, y_name in enumerate(y_data_list):
            # 获取颜色，超出范围时用红色
            color = y_colors[i] if i < len(y_colors) else "red"
            curve = self.plot_widget.plot(
                pen=pg.mkPen(color=color, width=4.0), 
                name=y_name
            )
            self.curves[y_name] = curve
    
    def update_data(self, data_dict: Dict[str, deque]) -> None:
        """更新图表数据"""
        x_data_name = self.config.get('x_data')
        if not x_data_name:
            return
        
        x_data = data_dict.get(x_data_name)
        if not x_data:
            return
        
        x_array = np.array(x_data)
        
        for y_name, curve in self.curves.items():
            y_data = data_dict.get(y_name)
            if not y_data:
                continue
            y_array = np.array(y_data)
            curve.setData(x_array, y_array)

class ChartManager(QObject):
    """图表管理器 - 职责单一，数据结构清晰"""

    message_signal = pyqtSignal(str)
    
    def __init__(self, main_window, data_service, chart_json_path: str = 'config/chart.json'):
        super().__init__()
        self.main_window = main_window
        self.data_service = data_service
        
        # 统一的图表存储：{tab_name: {chart_key: Chart}}
        self.charts: Dict[str, Dict[str, Chart]] = {}
        
        # 加载配置并初始化
        self.chart_config = self._load_chart_config(chart_json_path)
        if self.chart_config:
            self._setup_pyqtgraph()
            self._setup_all_charts()

    def _load_chart_config(self, path: str) -> Optional[Dict[str, Any]]:
        """加载图表配置文件"""
        try:
            with open(path, 'r', encoding='utf-8') as f:
                return json.load(f)
        except (FileNotFoundError, json.JSONDecodeError) as e:
            self.message_signal.emit(f"配置文件读取失败: {e}")
            return None
    
    def _setup_pyqtgraph(self) -> None:
        """配置pyqtgraph全局设置"""
        pg.setConfigOption('background', '#FFFFFF')
        pg.setConfigOption('foreground', 'k')
    
    def _setup_all_charts(self) -> None:
        """设置所有图表"""
        for tab_name, tab_config in self.chart_config.items():
            # 设置单个标签页的所有图表
            # 获取标签页布局
            if not hasattr(self.main_window, tab_name):
                self.message_signal.emit(f"警告: 找不到标签页布局 '{tab_name}'")
                continue
            layout = getattr(self.main_window, tab_name)
        
            self.charts[tab_name] = {}
            
            # 遍历标签页中的所有图表配置
            for chart_key, chart_config in tab_config.items():
                if not chart_key.startswith('chart'):
                    continue
                
                # 创建图表并添加到布局
                chart = Chart(chart_config)
                layout.addWidget(chart.plot_widget)
                self.charts[tab_name][chart_key] = chart

    def update_all_charts(self) -> None:
        """更新所有图表数据"""
        if not self.charts:
            return
        
        for tab_name, tab_item in self.charts.items():
            for chart_key, chart in tab_item.items():
                if not chart.data_source:
                    continue
                data_dict = self.data_service.get_data(chart.data_source)
                if not data_dict:
                    continue
                chart.update_data(data_dict)
